package com.vshop.platform.system.crud.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ObjectUtil;

import com.vshop.framework.core.constant.Const;
import com.vshop.framework.core.exception.ServiceException;
import com.vshop.framework.core.util.MapstructUtil;
import com.vshop.framework.core.util.StringUtil;
import com.vshop.framework.core.util.TreeBuildUtil;
import com.vshop.framework.satoken.helper.LoginHelper;
import com.vshop.platform.system.crud.dao.SysMenuDao;
import com.vshop.platform.system.crud.dao.SysRoleMenuDao;
import com.vshop.platform.system.domain.entity.SysMenu;
import com.vshop.platform.system.domain.param.SysMenuParam;
import com.vshop.platform.system.domain.vo.SysMenuVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;


@Slf4j
@RequiredArgsConstructor
@Service
public class SysMenuService {

    private final SysMenuDao sysMenuDao;
    private final SysRoleMenuDao sysRoleMenuDao;

    /**
     * 查询系统菜单列表
     */
    public List<SysMenuVo> list(SysMenuParam param, Long userId) {
        // 管理员显示所有菜单信息
        if (LoginHelper.isSuperAdmin(userId)) {
            return sysMenuDao.listAs(sysMenuDao.buildAdminQueryWrapper(), SysMenuVo.class);
        }
        return sysMenuDao.listAs(sysMenuDao.buildUserQueryWrapper(userId), SysMenuVo.class);
    }

    public boolean save(SysMenuParam param) {
        if (sysMenuDao.checkExistMenuName(param)) {
            throw new ServiceException("新增菜单'" + param.getMenuName() + "'失败，菜单名称已存在");
        }
        if (ObjectUtil.equals(0, param.getIsFrame()) && StringUtil.isNotHttp(param.getPath())) {
            throw new ServiceException("新增菜单'" + param.getMenuName() + "'失败，请填写http(s)://开头的路径");
        }
        SysMenu entity = MapstructUtil.convert(param, SysMenu.class);
        return sysMenuDao.save(entity);
    }

    public boolean update(SysMenuParam param) {
        if (sysMenuDao.checkExistMenuName(param)) {
            throw new ServiceException("修改菜单'" + param.getMenuName() + "'失败，菜单名称已存在");
        }
        if (ObjectUtil.equals(0, param.getIsFrame()) && StringUtil.isNotHttp(param.getPath())) {
            throw new ServiceException("修改菜单'" + param.getMenuName() + "'失败，请填写http(s)://开头的路径");
        }
        if (ObjectUtil.equals(param.getMenuId(), param.getParentId())) {
            throw new ServiceException("修改菜单'" + param.getMenuName() + "'失败，上级菜单不能选择自己");
        }
        SysMenu entity = MapstructUtil.convert(param, SysMenu.class);
        return sysMenuDao.updateById(entity);
    }

    public boolean removeById(Long menuId) {
        if (sysMenuDao.hasChildByMenuId(menuId)) {
            throw new ServiceException("存在子菜单不支持删除");
        }
        if (sysMenuDao.checkMenuHasRoleByMenuId(menuId)) {
            throw new ServiceException("菜单已分配角色，不允许删除");
        }
        return sysMenuDao.removeById(menuId);
    }


    /**
     * 构建前端所需要树结构 (正常状态)
     */
    public List<Tree<Long>> tree(Long userId) {
        SysMenuParam bo = new SysMenuParam();
        bo.setStatus(Const.StatusNormal);

        List<SysMenuVo> list = this.list(bo, userId);
        if (CollUtil.isEmpty(list)) {
            return CollUtil.newArrayList();
        }

        return TreeBuildUtil.build(list, (menu, tree) ->
                tree.setId(menu.getMenuId())
                        .setParentId(menu.getParentId())
                        .setName(menu.getMenuName())
                        .setWeight(menu.getSortNum()));
    }

    /**
     * 根据角色ID查询菜单树信息(已分配)
     *
     * @param roleId 角色ID
     * @return 选中菜单列表
     */
    public List<Long> listAllocatedMenuIdByRoleId(Long roleId) {
        return sysRoleMenuDao.listAllocatedMenuIdByRoleId(roleId);
    }

}
